package com.practice.designMode.single;

public class Singleton {
//    //饿汉式
//    private static final Singleton singleton = new Singleton();
//
//    private Singleton(){}
//
//    public static Singleton getInstance(){
//        return singleton;
//    }

//    //懒汉式
//    private static Singleton singleton;
//
//    private Singleton(){}
//
//    public static synchronized Singleton getInstance(){
//        if(singleton==null){
//            singleton = new Singleton();
//        }
//        return singleton;
//    }

    //双重检验锁 实际上是更加高效的懒汉模式
    /**
     * 这里volatile关键字声明是必须的
     * singleton = new Singleton();这句代码实际上进行了三步操作
     * 1.为Singleton实例分配内存空间
     * 2.对Singleton进行初始化
     * 3.将singleton指向分配的内存地址
     * 在多线程环境下，有可能出现顺序重排序，1-3-2，则在singleton指向分配地址时，没有进行初始化后有线程获取了一个没有初始化的Singleton实例
     * 所以需要volatile关键字，禁止对singleton有关操作进行重排序
     */
    private static volatile Singleton singleton;

    private Singleton(){}

    public static Singleton getInstance(){
        if(singleton==null){
            synchronized (Singleton.class){
                if(singleton==null){
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }

}
